﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Data;
using System.Data.SqlClient;

using SIPO.Library;
using SIPO.Library.DomainObject.Administration.Catalog;
using SIPO.Library.DomainObject.Administration.UserManagement;
using SIPO.Library.DomainObject.Transaction;
using SIPO.Library.Enum;
using SIPO.Library.Interfaces;

namespace SIPO.Library.DataAccess.Transaction
{
    public partial class recCalculationRepo : IRepository<recCalculation, int>
    {
        public object SelectScalar(SQL.Function.Aggregate function, string column, string parameters)
        {
            object _result = null;
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    StringBuilder sbQuery = new StringBuilder();
                    switch (function)
                    {
                        case SQL.Function.Aggregate.Max:
                            sbQuery.AppendFormat("SELECT MAX({0}) FROM transactions.recCalculation", column);
                            break;
                        case SQL.Function.Aggregate.Min:
                            sbQuery.AppendFormat("SELECT MIN({0}) FROM transactions.recCalculation", column);
                            break;
                        case SQL.Function.Aggregate.Distinct:
                            sbQuery.AppendFormat("SELECT DISTINCT({0}) FROM transactions.recCalculation", column);
                            break;
                        case SQL.Function.Aggregate.Count:
                            sbQuery.AppendFormat("SELECT COUNT({0}) FROM transactions.recCalculation", column);
                            sbQuery.AppendFormat("      inner join transactions.recBilling on transactions.recBilling.CalculationID=transactions.recCalculation.CalculationID ");
                            sbQuery.AppendFormat("      inner join transactions.recImpositionDetail on transactions.recImpositionDetail.ImpositionDetailID=transactions.recCalculation.ImpositionDetailID ");
                            sbQuery.AppendFormat("      inner join transactions.recImposition on transactions.recImposition.ImpositionID=transactions.recImpositionDetail.ImpositionID {0} ", parameters);
                            break;
                        case SQL.Function.Aggregate.Sum:
                            sbQuery.AppendFormat("SELECT SUM({0}) FROM transactions.recCalculation", column);
                            break;
                        case SQL.Function.Aggregate.Avg:
                            sbQuery.AppendFormat("SELECT AVG({0}) FROM transactions.recCalculation", column);
                            break;
                        default:
                            // do nothing 
                            break;
                    }

                    cmd.CommandText = sbQuery.ToString();
                    cmd.CommandType = CommandType.Text;
                    try
                    {
                        conn.Open();
                        _result = cmd.ExecuteScalar();
                    }
                    catch (Exception ex)
                    {
                        throw (ex);
                    }
                    finally
                    {
                        if (conn.State == ConnectionState.Open) conn.Close();
                    }
                }
            }
            return _result;
        }
        public List<recCalculation> GetList(int pageSize, int currentPage, string sortName, string sortOrder, string parameters)
        {
            List<recCalculation> tt = new List<recCalculation>();
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    int startRow = ((currentPage - 1) * pageSize) + 1;
                    int endRow = (startRow + pageSize);

                    StringBuilder sbQuery = new StringBuilder();
                    sbQuery.AppendFormat(" WITH result_set AS ");
                    sbQuery.AppendFormat(" ( ");
                    sbQuery.AppendFormat("    SELECT ");
                    sbQuery.AppendFormat("      ROW_NUMBER() OVER (ORDER BY {0} {1}) AS [row_number], ", sortName, sortOrder);
                    sbQuery.AppendFormat("      transactions.recCalculation.CalculationID,transactions.recCalculation.DebtorID,transactions.recCalculation.DebtorSectorID, transactions.recCalculation.YearDues,transactions.recBilling.Value ");
                    sbQuery.AppendFormat("      ,transactions.recBilling.ForPayment,transactions.recBilling.DueDate,transactions.recBilling.Balance ");
                    sbQuery.AppendFormat("    FROM ");
                    sbQuery.AppendFormat("      transactions.recCalculation ");
                    sbQuery.AppendFormat("      inner join transactions.recBilling on transactions.recBilling.CalculationID=transactions.recCalculation.CalculationID ");
                    sbQuery.AppendFormat("      inner join transactions.recImpositionDetail on transactions.recImpositionDetail.ImpositionDetailID=transactions.recCalculation.ImpositionDetailID ");
                    sbQuery.AppendFormat("      inner join transactions.recImposition on transactions.recImposition.ImpositionID=transactions.recImpositionDetail.ImpositionID ");
                    sbQuery.AppendFormat(" {0} ) ", parameters);
                    sbQuery.AppendFormat(" SELECT * FROM result_set WHERE [row_number] BETWEEN {0} AND {1} ", startRow, endRow);

                    cmd.CommandText = sbQuery.ToString();
                    cmd.CommandType = CommandType.Text;
                    try
                    {
                        conn.Open();
                        using (SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                        {
                            while (dr.Read())
                            {
                                recCalculation t = new recCalculation(true);
                                t.CalculationID = dr[recCalculation.Fields.CalculationID] == DBNull.Value ? 0 : int.Parse(dr[recCalculation.Fields.CalculationID].ToString());
                                t.DebtorSectorID = dr[recCalculation.Fields.DebtorSectorID] == DBNull.Value ? (int?)null : int.Parse(dr[recCalculation.Fields.DebtorSectorID].ToString());
                                t.YearDues = dr[recCalculation.Fields.YearDues] == DBNull.Value ? (int?)null : int.Parse(dr[recCalculation.Fields.YearDues].ToString());
                                t.DebtorID = dr[recCalculation.Fields.DebtorID] == DBNull.Value ? (int?)null : int.Parse(dr[recCalculation.Fields.DebtorID].ToString());
                                t.recBilling.Value = dr[recBilling.Fields.Value] == DBNull.Value ? 0 : decimal.Parse(dr[recBilling.Fields.Value].ToString());
                                t.recBilling.ForPayment = dr[recBilling.Fields.ForPayment] == DBNull.Value ? string.Empty : dr[recBilling.Fields.ForPayment].ToString();
                                t.recBilling.DueDate = dr[recBilling.Fields.DueDate] == DBNull.Value ? (DateTime?)null : DateTime.Parse(dr[recBilling.Fields.DueDate].ToString());
                                t.recBilling.Balance = dr[recBilling.Fields.Balance] == DBNull.Value ? 0 : decimal.Parse(dr[recBilling.Fields.Balance].ToString());
                                tt.Add(t);
                                t.Dispose();
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        throw (ex);
                    }
                    finally
                    {
                        if (conn.State == ConnectionState.Open) conn.Close();
                    }
                }
            }
            return tt;
        }
        public bool Save(string userLogin)
        {
            bool result = false;
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                conn.Open();
                SqlTransaction txn = conn.BeginTransaction();
                try
                {
                    string strExecuteSp = "[dbo].[SP_GenPeriodicDuesKoreksi]";
                    SqlCommand cmdExecuteSp = new SqlCommand(strExecuteSp, conn);
                    cmdExecuteSp.CommandType = CommandType.StoredProcedure;
                    cmdExecuteSp.Parameters.Add("@pDebtorID", SqlDbType.VarChar).Value = string.Empty;
                    cmdExecuteSp.Parameters.Add("@Param3", SqlDbType.VarChar).Value = userLogin;
                    cmdExecuteSp.Parameters.Add("@YearRep", SqlDbType.VarChar).Value = DBNull.Value;
                    cmdExecuteSp.Parameters.Add("@param2", SqlDbType.VarChar).Value = string.Empty;
                    cmdExecuteSp.CommandTimeout = 0;
                    cmdExecuteSp.Transaction = txn;
                    cmdExecuteSp.ExecuteNonQuery();
                    cmdExecuteSp.Dispose();
                    result = true;
                    txn.Commit();
                }
                catch (Exception ex)
                {
                    txn.Rollback();
                    throw (ex);
                }
                finally
                {
                    if (conn.State == ConnectionState.Open) conn.Close();
                }

            }
            return result;
        }
        public bool Save(int debtorid, string userLogin)
        {
            bool result = false;
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                conn.Open();
                SqlTransaction txn = conn.BeginTransaction();
                try
                {
                    string strExecuteSp = "[dbo].[SP_GenPeriodicDues]";
                    SqlCommand cmdExecuteSp = new SqlCommand(strExecuteSp, conn);
                    cmdExecuteSp.CommandType = CommandType.StoredProcedure;
                    cmdExecuteSp.Parameters.Add("@pDebtorID", SqlDbType.VarChar).Value = debtorid;
                    cmdExecuteSp.Parameters.Add("@Param3", SqlDbType.VarChar).Value = userLogin;
                    cmdExecuteSp.Parameters.Add("@param2", SqlDbType.VarChar).Value = string.Empty;
                    cmdExecuteSp.CommandTimeout = 0;
                    cmdExecuteSp.Transaction = txn;
                    cmdExecuteSp.ExecuteNonQuery();
                    cmdExecuteSp.Dispose();

                    result = true;
                    txn.Commit();
                }
                catch (Exception ex)
                {
                    txn.Rollback();
                    throw (ex);
                }
                finally
                {
                    if (conn.State == ConnectionState.Open) conn.Close();
                }

            }
            return result;
        }
    }
}
